import copy
import calendar
from dateutil.relativedelta import relativedelta
from datetime import datetime, timedelta, date

from odoo import fields, models, api
from odoo.osv import expression
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT


class OperatingStatements(models.Model):
    _name = 's.operating.statements'
    _description = 'Operating Statements'
    _order = 's_date'

    s_date = fields.Date('Date', copy=False, required=True)

    sales_value = fields.Float('sales value', copy=False, default=0.0)  # 销售产值
    sales_return_value = fields.Float('sales return value', copy=False, default=0.0)  # 退货扣减价值
    return_inspection_and_storage_value = fields.Float('Return inspection and storage', copy=False, default=0.0)  # 返检入库增加价值
    customer_quality_deduction_value = fields.Float('sales value', copy=False, default=0.0)  # 客户品质扣款
    finished_goods_warehouse_loss_deduction_value = fields.Float(string="成品仓盘亏扣减价值", copy=False, default=0.0)
    single_process_processing_income = fields.Float(string="单工序加工收入", copy=False, default=0.0)
    single_process_processing_compensation = fields.Float(string="单工序加工赔偿", copy=False, default=0.0)
    other_business_income_scrap_income = fields.Float(string="其它业务收入-废料收入", copy=False, default=0.0)

    raw_materials_plate = fields.Float(string="原材料-板料", copy=False, default=0.0)
    raw_materials_prepreg = fields.Float(string="原材料-半固化片", copy=False, default=0.0)
    raw_materials_copper_foil = fields.Float(string="原材料-铜箔", copy=False, default=0.0)
    raw_materials_ink = fields.Float(string="原材料-油墨", copy=False, default=0.0)
    raw_materials_dry_film = fields.Float(string="原材料-干膜", copy=False, default=0.0)
    components_and_copper_blocks = fields.Float(string="器件&铜块", copy=False, default=0.0)

    raw_materials_copper_balls_copper_powder = fields.Float(string="原材料-铜球，氧化铜粉", copy=False, default=0.0)
    raw_materials_tin_balls_tin_bars_nickel_blocks = fields.Float(string="原材料-锡球，锡条，镍块", copy=False, default=0.0)
    raw_materials_potassium_gold_cyanide = fields.Float(string="原材料-氰化亚金钾", copy=False, default=0.0)
    raw_materials_packaging_wire = fields.Float(string="原材料-包线", copy=False, default=0.0)
    raw_materials_drill_bits_routing_bits_slotting_bits = fields.Float(string="原材料-钻咀、锣刀、槽刀", copy=False, default=0.0)

    other_materials = fields.Float(string="其它物料", copy=False, default=0.0)
    basic_chemicals = fields.Float(string="基础药水", copy=False, default=0.0)
    packaging_wire_chemical_costs = fields.Float(string="包线药水费用", copy=False, default=0.0)

    single_process_outsourcing = fields.Float(string="单制程外包", copy=False, default=0.0)
    full_process_outsourcing = fields.Float(string="全制程外包", copy=False, default=0.0)

    production_wages = fields.Float(string="生产工资", copy=False, default=0.0)
    quality_wages = fields.Float(string="品质工资", copy=False, default=0.0)
    technical_department_wages = fields.Float(string="技术部工资", copy=False, default=0.0)

    production_electricity_usage = fields.Float(string="生产使用电", copy=False, default=0.0)
    production_water_usage = fields.Float(string="生产使用水", copy=False, default=0.0)
    production_gas_usage = fields.Float(string="生产使用燃气", copy=False, default=0.0)

    finished_goods_warehouse = fields.Float(string="成品仓", copy=False, default=0.0)
    chemicals_warehouse = fields.Float(string="药水仓", copy=False, default=0.0)
    raw_materials_warehouse = fields.Float(string="物料仓", copy=False, default=0.0)

    sales_expenses = fields.Float(string="销售费用", copy=False, default=0.0)
    variable_expenses = fields.Float(string="变动销费", copy=False, default=0.0)
    business_salaries_and_bonus = fields.Float(string="业务薪资&奖金", copy=False, default=0.0)
    transportation_fees = fields.Float(string="运输费", copy=False, default=0.0)

    fixed_indirect_labor = fields.Float(string="固定间接人工", copy=False, default=0.0)
    meals_and_accommodation = fields.Float(string="餐费/住宿费", copy=False, default=0.0)
    welfare_expenses = fields.Float(string="福利费", copy=False, default=0.0)
    bonus_accrual = fields.Float(string="奖金计提", copy=False, default=0.0)
    depreciation_and_amortization = fields.Float(string="折旧/摊销", copy=False, default=0.0)
    maintenance_and_repair_fees = fields.Float(string="维修保养费用", copy=False, default=0.0)
    fixed_utilities = fields.Float(string="固定水电费", copy=False, default=0.0)
    environmental_protection_fees = fields.Float(string="环境保护费", copy=False, default=0.0)
    communication_fees = fields.Float(string="通讯费", copy=False, default=0.0)
    company_vehicle_expenses = fields.Float(string="公司车辆", copy=False, default=0.0)
    research_and_development_expenses = fields.Float(string="研发费用", copy=False, default=0.0)
    entertainment_and_travel_expenses = fields.Float(string="招待及差旅费", copy=False, default=0.0)
    other_fixed_expenses = fields.Float(string="其它固定费用", copy=False, default=0.0)
    non_operating_income_expenses = fields.Float(string="营业外收支", copy=False, default=0.0)
    financial_expenses = fields.Float(string="财务费用", copy=False, default=0.0)
    exchange_gain_loss = fields.Float(string="兑换盈亏", copy=False, default=0.0)

    def _compute_value_every_day(self):
        last_record = self.search([], limit=1, order='s_date desc')
        if last_record:
            s_date = last_record.s_date + timedelta(days=1)
        else:
            s_date = date.today() - timedelta(days=1)
        while s_date < date.today():
            value_dict = self._compute_value_dict(s_date)
            value_dict.update({'s_date': s_date})
            self.create(value_dict)
            s_date += timedelta(days=1)
            # break

    def _compute_value_dict(self, to_date):
        # start_date = fields.Datetime.to_datetime(to_date).replace(hour=1, minute=0, second=0, microsecond=0)
        # end_date = start_date + timedelta(days=1)

        start_date = fields.Datetime.to_datetime(to_date).replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(hours=7)
        end_date = start_date + timedelta(days=1)

        base_move_domain = [
            ('state', '=', 'done'),
            ('date', '>=', start_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)),
            ('date', '<', end_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)),
        ]

        # 计算 sales_value
        sales_value = self._compute_sales_value(copy.deepcopy(base_move_domain))

        # 芯板
        core_category_id = self.env['product.category'].search([('code', '=', 'CR')])
        raw_materials_plate = self._compute_raw_category_materials_value(core_category_id, copy.deepcopy(base_move_domain))
        # PP
        prepreg_category_id = self.env['product.category'].search([('code', '=', 'BS')])
        raw_materials_prepreg = self._compute_raw_category_materials_value(prepreg_category_id, copy.deepcopy(base_move_domain))
        # 原材料-铜箔
        foil_category_id = self.env['product.category'].search([('code', '=', 'FO')])
        raw_materials_copper_foil = self._compute_raw_category_materials_value(foil_category_id, copy.deepcopy(base_move_domain))
        # 原材料-油墨
        ink_category_id = self.env['product.category'].search([('code', '=', 'IK')])
        raw_materials_ink = self._compute_raw_category_materials_value(ink_category_id, copy.deepcopy(base_move_domain))
        # 原材料-干膜
        film_category_id = self.env['product.category'].search([('code', '=', 'DF')])
        raw_materials_dry_film = self._compute_raw_category_materials_value(film_category_id, copy.deepcopy(base_move_domain))
        # 原材料-铜球，氧化铜粉
        copper_balls_copper_powder = self.env['product.category'].search([('code', 'in', ('PMCO', 'PMCB'))])
        raw_materials_copper_balls_copper_powder = self._compute_raw_category_materials_value(copper_balls_copper_powder, copy.deepcopy(base_move_domain))
        # 原材料-锡球，锡条，镍块
        tin_balls_tin_bars_nickel_blocks = self.env['product.category'].search([('code', 'in', ('PMSL', 'PMSH', 'PMNR', 'PMLR', 'PMGR', 'PMFR'))])
        raw_materials_tin_balls_tin_bars_nickel_blocks = self._compute_raw_category_materials_value(tin_balls_tin_bars_nickel_blocks, copy.deepcopy(base_move_domain))
        #  原材料 - 氰化亚金钾
        potassium_gold_cyanide_category_id = self.env['product.category'].search([('code', '=', 'PMCA')])
        raw_materials_potassium_gold_cyanide = self._compute_raw_category_materials_value(potassium_gold_cyanide_category_id, copy.deepcopy(base_move_domain))
        #  原材料 - 氰化亚金钾
        drill_bits_routing_bits_slotting_bits_category_id = self.env['product.category'].search([('code', 'in', ('RTRT', 'RTDR', 'RTSL'))])
        raw_materials_drill_bits_routing_bits_slotting_bits = self._compute_raw_category_materials_value(drill_bits_routing_bits_slotting_bits_category_id, copy.deepcopy(base_move_domain))
        # 基础药水
        basic_chemicals_category_ids = self.env['product.category'].search([('code', 'in', ('CHNM', 'CHSP'))])
        basic_chemicals = self._compute_raw_category_materials_value(basic_chemicals_category_ids, copy.deepcopy(base_move_domain))

        # 制造部，其它物料
        category_code = [
            'CR', 'CRAL', 'CRBC', 'CRBT', 'CRCE', 'CRCH', 'CRCM', 'CRCU', 'CRF4', 'CRPE', 'CRPF', 'CRPI', 'CRPP',
            'BS', 'BSAD', 'BSBF', 'BSBT', 'BSCE', 'BSCH', 'BSCM', 'BSF4', 'BSPE', 'BSPF', 'BSPI', 'BSPP',
            'FO', 'FOBR', 'FOCF', 'FOCP', 'FOCR',
            'IK', 'IKAP', 'IKCB', 'IKIM', 'IKJT', 'IKLG', 'IKPL', 'IKPR', 'IKPS', 'IKSM',
            'DF', 'DFDI', 'DFNM', 'DFSD',

            'PMCO', 'PMCB', 'PMSL', 'PMSH', 'PMNR', 'PMLR', 'PMGR', 'PMFR',
            'PMCA', 'RTRT', 'RTDR', 'RTSL', 'CHNM', 'CHSP', 'CHP', 'BCP'
        ]
        department_id = self.env['hr.department'].search([('code', '=', 'MFG')], limit=1)
        other_materials_base_move_domain = expression.AND([copy.deepcopy(base_move_domain), [('picking_id.apply_department_id', '=', department_id.id)]])
        other_materials_category_ids = self.env['product.category'].search([('code', 'not in', category_code)])
        other_materials = self._compute_raw_category_materials_value(other_materials_category_ids, other_materials_base_move_domain, contain_child_category=False)

        # 计算委外
        single_process_outsourcing = self._compute_outsourcing(start_date, end_date)

        return {
            'sales_value': sales_value,
            'sales_return_value': 0,
            'return_inspection_and_storage_value': 0,
            'customer_quality_deduction_value': 0,
            'finished_goods_warehouse_loss_deduction_value': 0,
            'single_process_processing_income': 0,
            'single_process_processing_compensation': 0,
            'other_business_income_scrap_income': 0,
            'raw_materials_plate': raw_materials_plate,
            'raw_materials_copper_foil': raw_materials_copper_foil,
            'raw_materials_ink': raw_materials_ink,
            'raw_materials_prepreg': raw_materials_prepreg,
            'raw_materials_dry_film': raw_materials_dry_film,
            'components_and_copper_blocks': 0,
            'raw_materials_copper_balls_copper_powder': raw_materials_copper_balls_copper_powder,
            'raw_materials_tin_balls_tin_bars_nickel_blocks': raw_materials_tin_balls_tin_bars_nickel_blocks,
            'raw_materials_potassium_gold_cyanide': raw_materials_potassium_gold_cyanide,
            'raw_materials_packaging_wire': 0,
            'raw_materials_drill_bits_routing_bits_slotting_bits': raw_materials_drill_bits_routing_bits_slotting_bits,
            'basic_chemicals': basic_chemicals,
            'other_materials': other_materials,
            'packaging_wire_chemical_costs': 0,
            'single_process_outsourcing': single_process_outsourcing,
            'full_process_outsourcing': 0,
        }

    def _compute_outsourcing(self, start_date, end_date):
        """委外费用计算"""
        total = 0
        purchase_ids = self.env['purchase.order'].search([
            ('state', '=', 'purchase'),
            ('subcontracting', '!=', False),
            ('date_approve', '>=', start_date),
            ('date_approve', '<', end_date),
        ])
        for purchase in purchase_ids:
            total += purchase.currency_id._convert(purchase.amount_untaxed, purchase.company_id.currency_id, purchase.company_id, purchase.date_approve or fields.Date.today())
        return total / 10000

    def _compute_sales_value(self, base_domain):
        location_id = self.env['stock.location'].search([('barcode', '=', 'WH-PREPRODUCTION')], limit=1)
        location_dest_id = self.env['stock.location'].search([('barcode', '=', 'WH-STOCK-FINISHED-PRODUCT')], limit=1)
        location_dest_ids = location_dest_id + location_dest_id.child_ids
        sales_value_domain = copy.deepcopy(base_domain) + [
            ('location_id.usage', 'in', ('internal', 'production', 'inventory')),
            ('location_dest_id', 'in', location_dest_ids.ids),
            ('product_id.categ_id.code', 'in', ('CHP', 'OPFP')),
            ('s_report_not_counted', '!=', True)
        ]
        move_ids = self.env['stock.move'].search(base_domain + sales_value_domain)
        total = 0
        for line in move_ids.mapped('move_line_ids'):
            production = self.env['mrp.production'].search([('lot_producing_id', '=', line.lot_id.id)])
            sale_line = production.mapped('s_sale_order_line_ids')
            if not sale_line:
                continue
            price = sum(sale_line.mapped('price_reduce_taxexcl')) / len(sale_line)
            price = sale_line[0].currency_id._convert(
                price,
                self.env.company.currency_id,
                self.env.company,
                sale_line[0].order_id.date_order or fields.Date.today()
            )
            total += line.quantity * price
        return total / 10000  # 万元

    def _compute_raw_category_materials_value(self, category_ids, base_domain, contain_child_category=True):
        # categ_id = self.env['product.category'].search([('code', '=', 'CR')])
        if not category_ids:
            return 0
        if contain_child_category:
            category_ids = category_ids + category_ids.child_id
        out_domain = [
            ('product_id.categ_id', 'in', category_ids.ids),
            ('location_id.usage', '=', 'internal'),
            ('location_dest_id.usage', 'in', ('production', 'inventory'))
        ]
        out_move_ids = self.env['stock.move'].search(base_domain + out_domain)
        in_domain = [
            ('product_id.categ_id', 'in', category_ids.ids),
            ('location_dest_id.usage', '=', 'internal'),
            ('location_id.usage', 'in', ('production', 'inventory'))
        ]
        in_move_ids = self.env['stock.move'].search(base_domain + in_domain)
        out_stock_valuation_layer = self.env['stock.valuation.layer'].search([('stock_move_id', 'in', out_move_ids.ids)])
        in_stock_valuation_layer = self.env['stock.valuation.layer'].search([('stock_move_id', 'in', in_move_ids.ids)])
        total = abs(sum(out_stock_valuation_layer.mapped('value'))) - sum(in_stock_valuation_layer.mapped('value'))
        return round(total / 10000, 5)  # 万元

    @api.model
    def get_view_date_data(self, s_date=None):
        if not s_date:
            s_date = date.today() - timedelta(days=1)
        record = self.sudo().search([('s_date', '=', s_date)], limit=1)
        if isinstance(s_date, str):
            s_date = datetime.strptime(s_date, DEFAULT_SERVER_DATE_FORMAT).date()
        first_day = s_date.replace(day=1)
        _, last_day_num = calendar.monthrange(s_date.year, s_date.month)
        last_day = s_date.replace(day=last_day_num)
        records = self.sudo().search([('s_date', '>=', first_day), ('s_date', '<=', last_day)])

        # 获取百分比配置
        percentage = self.env['s.operating.statements.settings'].sudo().search([('year', '=', str(s_date.year)), ('month', '=', str(s_date.month).zfill(2))])
        fields_list = list(self._fields.keys())
        other_fields = ['id', 'write_uid', 'write_date', 'create_date', 'create_uid', 'display_name', 's_date']
        day_vals = {}
        month_vals = {}
        percentage_vals = {}
        for f in fields_list:
            if f in other_fields:
                continue
            day_vals[f] = round(getattr(record, f, 0), 3)
            month_vals[f'{f}_total'] = round(sum(records.mapped(f)), 3)
            percentage_vals[f] = round(getattr(percentage, f, 0) * 100, 2)
        return {
            'day_vals': day_vals,
            'month_vals': month_vals,
            'percentage_vals': percentage_vals
        }
        # return {
        #     'sales_value': record.sales_value,
        #     'sales_return_value': record.sales_return_value,
        #     'return_inspection_and_storage_value': record.return_inspection_and_storage_value,
        #     'customer_quality_deduction_value': record.customer_quality_deduction_value,
        #     'finished_goods_warehouse_loss_deduction_value': record.finished_goods_warehouse_loss_deduction_value,
        #     'single_process_processing_income': record.single_process_processing_income,
        #     'single_process_processing_compensation': record.single_process_processing_compensation,
        #     'other_business_income_scrap_income': record.other_business_income_scrap_income,
        #     'raw_materials_plate': record.raw_materials_plate,
        #     'raw_materials_copper_foil': record.raw_materials_copper_foil,
        #     'raw_materials_ink': record.raw_materials_ink,
        #     'raw_materials_prepreg': record.raw_materials_prepreg,
        #     'raw_materials_dry_film': record.raw_materials_dry_film,
        #     'components_and_copper_blocks': record.components_and_copper_blocks,
        #     'raw_materials_copper_balls_copper_powder': record.raw_materials_copper_balls_copper_powder,
        #     'raw_materials_tin_balls_tin_bars_nickel_blocks': record.raw_materials_tin_balls_tin_bars_nickel_blocks,
        #     'raw_materials_potassium_gold_cyanide': record.raw_materials_potassium_gold_cyanide,
        #     'raw_materials_packaging_wire': record.raw_materials_packaging_wire,
        #     'raw_materials_drill_bits_routing_bits_slotting_bits': record.raw_materials_drill_bits_routing_bits_slotting_bits,
        #     'basic_chemicals': record.basic_chemicals,
        #     'packaging_wire_chemical_costs': record.packaging_wire_chemical_costs,
        #     'single_process_outsourcing': record.single_process_outsourcing,
        #     'full_process_outsourcing': record.full_process_outsourcing,
        # }

    @api.model
    def get_label(self, year=None, month=None):
        label_list = ['一阶项目', '二阶项目(加/减)', '三阶内容', '负责部门']
        # 如果未指定年月，默认使用当前年月
        if year is None or month is None:
            today = datetime.now()
            year, month = today.year, today.month

        # 获取该月的最后一天
        if month == 12:
            next_month = datetime(year + 1, 1, 1)
        else:
            next_month = datetime(year, month + 1, 1)
        last_day_of_month = (next_month - datetime(year, month, 1)).days

        # 获取当天的日期
        today = datetime.now() - timedelta(days=1)
        current_day = today.day if today.year == year and today.month == month else last_day_of_month

        # 生成日期列表
        days_list = [str(day) + '号' for day in range(1, current_day + 1)]
        return label_list + days_list + ['月累计']

    def get_month_range_with_days(self, date_in_month):
        """获取指定日期所在月的月初、调整后的月底及总天数
        Args:
            date_in_month (datetime.date): 目标日期
        Returns:
            tuple: (first_day, last_day, total_days)
        """
        today = date.today()

        # 计算月初（固定为1号）
        first_day = date_in_month.replace(day=1)

        # 判断是否为当前月
        is_current_month = (first_day.year == today.year) and (first_day.month == today.month)

        # 计算月底
        if is_current_month:
            last_day = today - timedelta(days=1) # 当前月截止到前天
        else:
            # 非当前月则计算该月最后一天
            _, last_day_num = calendar.monthrange(first_day.year, first_day.month)
            last_day = first_day + relativedelta(months=1) - timedelta(days=1)

        # 计算总天数（包含首尾）
        total_days = (last_day - first_day).days + 2

        return first_day, last_day, total_days

    @api.model
    def get_data_list(self, x_date=None):
        if not x_date:
            x_date = date.today()
        else:
            x_date = fields.Date.to_date(datetime.strptime(x_date, DEFAULT_SERVER_DATE_FORMAT))
        first_day, last_day, days = self.get_month_range_with_days(x_date)
        records = self.search([('s_date', '>=', first_day), ('s_date', '<=', last_day)])
        # "一、产值
        # （Output value）"	投入产出收入		所有收入汇总
        data_list = []
        one = ['一、产值', '投入产出收入', '所有收入汇总', ''] + ['' for _ in range(days)]
        sales_value = ['', '销售产值', '入库数量*未税销售单价', '市场部']
        sales_return_value = ['', '退货扣减价值', '客户退货扣减产值', '品质部']
        return_inspection_and_storage_value = ['', '返检入库增加价值', '重新入库产值', '品质部']
        customer_quality_deduction_value = ['', '客户品质扣款', '客户索赔金额', '品质部']
        finished_goods_warehouse_loss_deduction_value = ['', '成品仓盘亏扣减价值', '盘点亏损减值', '运营部']
        single_process_processing_income = ['', '单工序加工收入', '代工收入', '运营部']
        single_process_processing_compensation = ['', '单工序加工赔偿', '代工品质索赔', '品质部']
        other_business_income_scrap_income = ['', '其它业务收入-废料收入', '废料收入', '设备管理部']

        two = ['二、直接材料', 'BOM材料成本', 'BOM物料总费用', ''] + ['' for _ in range(days)]
        raw_materials_plate = ['', '原材料-板料', '板料领用金额', '制造部']
        raw_materials_copper_foil = ['', '原材料-铜箔', '铜箔领用金额', '制造部']
        raw_materials_ink = ['', '原材料-油墨', '油墨领用金额', '制造部']
        raw_materials_prepreg = ['', '原材料-半固化片', '半固化片领用金额', '制造部']
        raw_materials_dry_film = ['', '原材料-干膜', '干膜领用金额', '制造部']
        components_and_copper_blocks = ['', '器件&铜块', '器件&铜块领用金额', '制造部']

        three = ['三. 直接物料', '非BOM物料', '', ''] + ['' for _ in range(days)]
        raw_materials_copper_balls_copper_powder = ['', '原材料-铜球，氧化铜粉', '铜球领用金额', '制造部']
        raw_materials_tin_balls_tin_bars_nickel_blocks = ['', '原材料-锡球，锡条，镍块', '锡球，锡条领用金额', '制造部']
        raw_materials_potassium_gold_cyanide = ['', '原材料-氰化亚金钾', '氰化亚金钾领用金额', '制造部']
        raw_materials_packaging_wire = ['', '原材料-包线', '包线金额', '制造部']
        raw_materials_drill_bits_routing_bits_slotting_bits = ['', '原材料-钻咀、锣刀、槽刀', '钻咀、锣刀、槽刀领用金额', '制造部']

        four = ['四. 辅助物料', '辅助物料费用', '', ''] + ['' for _ in range(days)]
        other_materials = ['', '其它物料', ' ', '制造部']
        basic_chemicals = ['', '基础药水', '', '制造部']
        packaging_wire_chemical_costs = ['', '包线药水费用', '', '制造部']

        five = ['五. 外包费用', '外包产生费用', '', ''] + ['' for _ in range(days)]
        single_process_outsourcing = ['', '单制程外包', '单制程外包费用', '运营部']
        full_process_outsourcing = ['', '全制程外包', '全制程外包费用', '运营部']

        six = ['六. 直接人工', '直接参与生产人员工资福利', '', ''] + ['' for _ in range(days)]
        production_wages = ['', '生产工资', '生产部门所有人员', '制造部']
        quality_wages = ['', '品质工资', '品质部门所有人员', '品质部']
        technical_department_wages = ['', '技术部工资', '研发，工艺，工程', '技术部']

        seven = ['七. 变动制费', '生产用水电费', '生产使用水电费', ''] + ['' for _ in range(days)]
        production_electricity_usage = ['', '生产使用电', '生产使用电费', '设备管理部']
        production_water_usage = ['', '生产使用水', '生产使用水费', '设备管理部']
        production_gas_usage = ['', '生产使用燃气', '生产使用燃气费', '设备管理部']

        eight = ['八. 呆滞损失', '物料呆滞损失', '', ''] + ['' for _ in range(days)]
        finished_goods_warehouse = ['', '成品仓', '成品呆滞报废', '运营部']
        chemicals_warehouse = ['', '药水仓', '药水呆滞报废', '运营部']
        raw_materials_warehouse = ['', '物料仓', '物料呆滞报废', '运营部']

        nine = ['九. 变动销费及其它', '销售相关费用', '', ''] + ['' for _ in range(days)]
        sales_expenses = ['', '销售费用', '计提：1.5%', '市场部']
        variable_expenses = ['', '变动销费', '市场部办公费、差旅费、交际费、办事处费用，电话费', '市场部']
        business_salaries_and_bonus = ['', '业务薪资&奖金', '市场部所有人的工资和奖金', '市场部']
        transportation_fees = ['', '运输费', '产品出货运费、报关费', '市场部']

        ten = ['十. 固定成本', '非生产相关，比较固定费用', '', ''] + ['' for _ in range(days)]
        fixed_indirect_labor = ['', '固定间接人工', '总经办、财务部、行政部、采购部、运营部、智能制造部，设备管理部', '总经办']
        meals_and_accommodation = ['', '餐费/住宿费', '员工餐费、住宿费', '行政部']
        welfare_expenses = ['', '福利费', '所有员工社保、商业保险，电话费', '行政部']
        bonus_accrual = ['', '奖金计提', '绩效奖金，年终奖金', '行政部']
        depreciation_and_amortization = ['', '折旧/摊销', '公司总折旧、土地、软件、房屋装修摊销+设备租赁', '总经办']
        maintenance_and_repair_fees = ['', '维修保养费用', '全厂维修及保养费', '设备管理部']
        fixed_utilities = ['', '固定水电费', '非生产用水用电', '行政部']
        environmental_protection_fees = ['', '环境保护费', '污水处理费+危废处置费', '设备管理部']
        communication_fees = ['', '通讯费', '网络费', '智能制造']
        company_vehicle_expenses = ['', '公司车辆', '厂车加油，维修，折旧费', '行政部']
        research_and_development_expenses = ['', '研发费用', '研发领用物料+外发加工', '技术部']
        entertainment_and_travel_expenses = ['', '招待及差旅费', '除业务部门报销费', '总经办']
        other_fixed_expenses = ['', '其它固定费用', '土地及房产税、财产保险、咨询及评估、品质体系及ERP服务费、UL, 培训，工会经费及其它', '财务部']
        non_operating_income_expenses = ['', '营业外收支', '政策性各种收支等', '财务部']
        financial_expenses = ['', '财务费用', '承兑，对外投资，利息，代理记账等费用', '财务部']
        exchange_gain_loss = ['', '兑换盈亏', '汇率造成收益或损失', '财务部']

        current = first_day
        while True:
            rec = records.filtered(lambda x: x.s_date == current)

            sales_value.append(round(rec.sales_value, 2))
            sales_return_value.append(round(rec.sales_return_value, 2))
            return_inspection_and_storage_value.append(round(rec.return_inspection_and_storage_value, 2))
            customer_quality_deduction_value.append(round(rec.customer_quality_deduction_value, 2))
            finished_goods_warehouse_loss_deduction_value.append(round(rec.finished_goods_warehouse_loss_deduction_value, 2))
            single_process_processing_income.append(round(rec.single_process_processing_income, 2))
            single_process_processing_compensation.append(round(rec.single_process_processing_compensation, 2))
            other_business_income_scrap_income.append(round(rec.other_business_income_scrap_income, 2))

            raw_materials_plate.append(round(rec.raw_materials_plate, 2))
            raw_materials_copper_foil.append(round(rec.raw_materials_copper_foil, 2))
            raw_materials_ink.append(round(rec.raw_materials_ink, 2))
            raw_materials_prepreg.append(round(rec.raw_materials_prepreg, 2))
            raw_materials_dry_film.append(round(rec.raw_materials_dry_film, 2))
            components_and_copper_blocks.append(round(rec.components_and_copper_blocks, 2))

            raw_materials_copper_balls_copper_powder.append(round(rec.raw_materials_copper_balls_copper_powder, 2))
            raw_materials_tin_balls_tin_bars_nickel_blocks.append(round(rec.raw_materials_tin_balls_tin_bars_nickel_blocks, 2))
            raw_materials_potassium_gold_cyanide.append(round(rec.raw_materials_potassium_gold_cyanide, 2))
            raw_materials_packaging_wire.append(round(rec.raw_materials_packaging_wire, 2))
            raw_materials_drill_bits_routing_bits_slotting_bits.append(round(rec.raw_materials_drill_bits_routing_bits_slotting_bits, 2))

            other_materials.append(round(rec.other_materials, 2))
            basic_chemicals.append(round(rec.basic_chemicals, 2))
            packaging_wire_chemical_costs.append(round(rec.packaging_wire_chemical_costs, 2))

            single_process_outsourcing.append(round(rec.single_process_outsourcing, 2))
            full_process_outsourcing.append(round(rec.full_process_outsourcing, 2))

            production_wages.append(round(rec.production_wages, 2))
            quality_wages.append(round(rec.quality_wages, 2))
            technical_department_wages.append(round(rec.technical_department_wages, 2))

            production_electricity_usage.append(round(rec.production_electricity_usage, 2))
            production_water_usage.append(round(rec.production_water_usage, 2))
            production_gas_usage.append(round(rec.production_gas_usage, 2))

            finished_goods_warehouse.append(round(rec.finished_goods_warehouse, 2))
            chemicals_warehouse.append(round(rec.chemicals_warehouse, 2))
            raw_materials_warehouse.append(round(rec.raw_materials_warehouse, 2))

            sales_expenses.append(round(rec.sales_expenses, 2))
            variable_expenses.append(round(rec.variable_expenses, 2))
            business_salaries_and_bonus.append(round(rec.business_salaries_and_bonus, 2))
            transportation_fees.append(round(rec.transportation_fees, 2))

            fixed_indirect_labor.append(round(rec.fixed_indirect_labor, 2))
            meals_and_accommodation.append(round(rec.meals_and_accommodation, 2))
            welfare_expenses.append(round(rec.welfare_expenses, 2))
            bonus_accrual.append(round(rec.bonus_accrual, 2))
            depreciation_and_amortization.append(round(rec.depreciation_and_amortization, 2))
            maintenance_and_repair_fees.append(round(rec.maintenance_and_repair_fees, 2))
            fixed_utilities.append(round(rec.fixed_utilities, 2))
            environmental_protection_fees.append(round(rec.environmental_protection_fees, 2))
            communication_fees.append(round(rec.communication_fees, 2))
            company_vehicle_expenses.append(round(rec.company_vehicle_expenses, 2))
            research_and_development_expenses.append(round(rec.research_and_development_expenses, 2))
            entertainment_and_travel_expenses.append(round(rec.entertainment_and_travel_expenses, 2))
            other_fixed_expenses.append(round(rec.other_fixed_expenses, 2))
            non_operating_income_expenses.append(round(rec.non_operating_income_expenses, 2))
            financial_expenses.append(round(rec.financial_expenses, 2))
            exchange_gain_loss.append(round(rec.exchange_gain_loss, 2))

            current = current + timedelta(days=1)
            if current > last_day:
                break

        result = [
            one, sales_value, sales_return_value, return_inspection_and_storage_value, customer_quality_deduction_value,
            finished_goods_warehouse_loss_deduction_value, single_process_processing_income,
            single_process_processing_compensation, other_business_income_scrap_income,

            two, raw_materials_plate, raw_materials_copper_foil, raw_materials_ink, raw_materials_prepreg,
            raw_materials_dry_film, components_and_copper_blocks,

            three,
            raw_materials_copper_balls_copper_powder,
            raw_materials_tin_balls_tin_bars_nickel_blocks,
            raw_materials_potassium_gold_cyanide,
            raw_materials_packaging_wire,
            raw_materials_drill_bits_routing_bits_slotting_bits,

            four,
            other_materials,
            basic_chemicals,
            packaging_wire_chemical_costs,

            five,
            single_process_outsourcing,
            full_process_outsourcing,

            six,
            production_wages,
            quality_wages,
            technical_department_wages,

            seven,
            production_electricity_usage,
            production_water_usage,
            production_gas_usage,

            eight,
            finished_goods_warehouse,
            chemicals_warehouse,
            raw_materials_warehouse,

            nine,
            sales_expenses,
            variable_expenses,
            business_salaries_and_bonus,
            transportation_fees,

            ten,
            fixed_indirect_labor,
            meals_and_accommodation,
            welfare_expenses,
            bonus_accrual,
            depreciation_and_amortization,
            maintenance_and_repair_fees,
            fixed_utilities,
            environmental_protection_fees,
            communication_fees,
            company_vehicle_expenses,
            research_and_development_expenses,
            entertainment_and_travel_expenses,
            other_fixed_expenses,
            non_operating_income_expenses,
            financial_expenses,
            exchange_gain_loss,
        ]
        for res in result:
            if len(res) >= 5 and isinstance(res[4], float):
                res.append(round(sum(res[4::]), 2))

        return {
            'header': self.get_label(x_date.year, x_date.month),
            'lines': result
        }
